

********************************************************************************
* Figure 7: Daily Decomposition of the 3-day FOMC window
********************************************************************************

*********************************
* (B) Intraday data
*********************************

use "../data/govpx/govpx_ontherun10y.dta", clear

*Generate the number of quotes per day
bysort date: egen count_quote = count(midyld)
bysort date: egen count_ind = count(indmyld)

*Determine which data to use
generate quote_data = (count_quote > count_ind - 20) * (count_quote > 40)
summarize count_quote if quote_data == 1, detail
summarize count_ind if quote_data == 0, detail

*Generate yield data based on the indicator
generate yld = midyld 	if quote_data == 1
replace yld = indmyld 	if quote_data == 0
drop if missing(yld)

*Define trading times during the day
global start_trading = 540 //9:00
global end_trading = 1020 //17:00
keep if trading_min >= $start_trading & trading_min <= $end_trading

*Keep other pricing data that is not needed (Use only the mid quotes)
drop bidprc bidyld askprc askyld indbid indbyld indask indayld 

*Generate week day
generate day = dow(date)
generate weekday = "Sunday" 	if day == 0
replace weekday = "Monday" 		if day == 1
replace weekday = "Tuesday" 	if day == 2
replace weekday = "Wednesday" 	if day == 3
replace weekday = "Thursday" 	if day == 4
replace weekday = "Friday" 		if day == 5
replace weekday = "Saturday" 	if day == 6
drop day

*Drop Saturdays and Sundays
drop if weekday == "Saturday" | weekday == "Sunday"
drop weekday

*********************************
* Determine which days fall inside and outside of FOMC window	
*********************************

*Load the FOMC meeting data
preserve 
	use "../data/final_data_fed_secular_decline", clear
	keep date fomc_meet scheduled sveny10_chg usgg10_chg
	
	*Keep dates within time where intraday data is available
	keep if date >= mdy(1,1,1994)
	keep if date < mdy(12,31,2020)

	*Drop the 3 meeting days where the announcement was prior to 14:15
	replace fomc_meet = . if date == td(04feb1994)
	replace fomc_meet = . if date == td(26mar1996)
	replace fomc_meet = . if date == td(15mar2020)
	
	*Keep only 4 days around the FOMC meetings
		//3-day window plus the day prior to the window
	keep if (fomc_meet[_n+2] == 1 & scheduled[_n+2] == 1) | (fomc_meet[_n+1] == 1 & scheduled[_n+1] == 1) | (fomc_meet == 1 & scheduled == 1) | (fomc_meet[_n-1] == 1 & scheduled[_n-1] == 1)
	
	*Numerate the meetings
	bysort fomc_meet (date): generate no_fomc = _n if fomc_meet == 1
	sort date
	replace no_fomc = no_fomc[_n+2] if fomc_meet[_n+2] == 1
	replace no_fomc = no_fomc[_n+1] if fomc_meet[_n+1] == 1
	replace no_fomc = no_fomc[_n-1] if fomc_meet[_n-1] == 1
	
	*Classify the days
	generate day_type = "fomc" 	if fomc_meet == 1
	replace day_type = "pre" 	if fomc_meet[_n+1] == 1
	replace day_type = "pre2" 	if fomc_meet[_n+2] == 1
	replace day_type = "post" 	if fomc_meet[_n-1] == 1
	
	tempfile fomc_meetings
	save	`fomc_meetings'
restore 

*Keep only the FOMC meeting days
merge m:1 date using `fomc_meetings', keep(3) nogen

*Fill-in missing observations (5min interval)
sort date trading_min	
tsset date trading_min
fillin date trading_min

*Replace missing "day_type"
bysort date (day_type): replace day_type = day_type[_N] if missing(day_type)
bysort date (day_type): replace no_fomc = no_fomc[_N] if missing(no_fomc)

*Replace missing yields
bysort no_fomc (date trading_min): replace yld = yld[_n-1] if missing(yld)
	
*From the day 2days before the meeting keep only the close
bysort no_fomc day_type (trading_min): drop if _n < _N & day_type == "pre2"

*Generate intraday cumulative yield change
bysort no_fomc (date trading_min): generate yld_at_first = yld[1]
generate cum_yld_chg = yld - yld_at_first

*Choose the confidence interval
global z = 1.645 //90% confidence interval

*********************************
* Compute yield changes based on the daily data	
*********************************

*GSW data: 3pm daily yield data
preserve
	keep  date datetime no_fomc day_type trading_min sveny10_chg
	
	*Drop all days that lie 2 days before the FOMC meeting
	drop if day_type == "pre2"
	
	*Keep last observation per day
	bysort date (trading_min): keep if _n == _N

	*Cumulate the yield changes within the windows
	bysort no_fomc (datetime): generate cum_sveny10_chg = sum(sveny10_chg)
	
	*Collapsing need number of FOMC meetings and the standard deviation	
	collapse (sum) cum_sveny10_chg ///
	(sd) sd_cum_sveny10_chg=cum_sveny10_chg ///
	(max) n=no_fomc ///
	, by(day_type)
	
	*Confidence interval
	generate se_10y_gsw = sd_cum_sveny10_chg / sqrt(n) * n
	generate conf_up_10y_gsw = cum_sveny10_chg + $z * se_10y_gsw 
	generate conf_down_10y_gsw = cum_sveny10_chg - $z * se_10y_gsw 	
	drop n se_10y_gsw
						
	generate trading_min = 900
	tempfile 3pm_daily_data
	save	`3pm_daily_data'
restore
		
*Bloomberg data: 5.15 pm daily yield data (Keep only the last observation per day)
preserve
	keep  date datetime no_fomc day_type trading_min usgg10_chg
	
	*Drop all days that lie 2 days before the FOMC meeting
	drop if day_type == "pre2"
	
	*Keep last observation per day
	bysort date (trading_min): keep if _n == _N

	*Cumulate the yield changes within the windows
	bysort no_fomc (datetime): generate cum_usgg10_chg = sum(usgg10_chg)
	
	*Collapsing need number of FOMC meetings and the standard deviation		
	collapse (sum) cum_usgg10_chg ///
	(sd) sd_cum_usgg10_chg=cum_usgg10_chg ///
	(max) n=no_fomc ///
	, by(day_type)
	
	*Confidence interval
	generate se_10y_bb = sd_cum_usgg10_chg / sqrt(n) * n
	generate conf_up_10y_bb = cum_usgg10_chg + $z * se_10y_bb 
	generate conf_down_10y_bb = cum_usgg10_chg - $z * se_10y_bb 	
	drop n se_10y_bb
		
	generate trading_min = 1020
	tempfile 5pm_daily_data
	save	`5pm_daily_data'
restore
	
*********************************
* Cumulate yield changes through the 3-day window
*********************************	
		
*Cumulate the yield changes in the intraday data
collapse (sum) cum_yld_chg ///
			(sd) sd_cum_yld_chg = cum_yld_chg ///
			(count) count=cum_yld_chg ///
			(max) n=no_fomc ///
			(lastnm) time ///
			, by(trading_min day_type)
sort day_type trading_min

*Confidence interval for intraday data
generate se_intraday = sd_cum_yld_chg / sqrt(n) * n
generate conf_up_intraday = cum_yld_chg + $z * se_intraday 
generate conf_down_intraday = cum_yld_chg - $z * se_intraday 	
drop n se_intraday

*Merge-in the daily change data
merge 1:1 day_type trading_min using `3pm_daily_data', nogen
merge 1:1 day_type trading_min using `5pm_daily_data', nogen
		
*********************************
* Generate graph
*********************************		
	
*Keep only one observation for the day "pre2"	
drop if day_type == "pre2" & trading_min < $end_trading //Keep only the 17:00 observation
	
*Generate plot
generate plot_time = trading_min - $end_trading						if day_type == "pre"
replace plot_time = trading_min - $start_trading					if day_type == "fomc"
replace plot_time = trading_min + $end_trading - 2*$start_trading 	if day_type == "post"
replace plot_time = - $end_trading + $start_trading -0.083333		if day_type == "pre2"
replace plot_time = plot_time / 60
sort plot_time

*Drop the closing prices // similar to opening prices
replace plot_time = plot_time-0.01  if trading_min == $end_trading & day_type != "post"
sort plot_time

drop if day_type == "pre2"

*Plot with FOMC meeting line (and daily data)
twoway 	(rarea conf_up_intraday conf_down_intraday plot_time, color(gs14)) || /// 
	(line cum_yld_chg plot_time, ///
	xticks(#28) ///
	xline(0 8, lcolor(gs3)) ///
	///
	xtitle("Hours since start of 3-day FOMC window") ///
	ytitle("Cumulative yield change (%)") ///
	xlabel(-8 "9:00" 0 "9:00" 5 "14:00" 8 "9:00" 16 "17:00")) || ///
	(scatter cum_usgg10_chg cum_sveny10_chg plot_time, ///
	msize(small small small) color(green navy)) || ///
	(rspike conf_up_10y_gsw conf_down_10y_gsw plot_time, lcolor(navy)) || ///
	(rcap conf_up_10y_gsw conf_up_10y_gsw plot_time, lcolor(navy) msize(*1)) || ///
	(rcap conf_down_10y_gsw conf_down_10y_gsw plot_time, lcolor(navy) msize(*1)) || ///
	(rspike conf_up_10y_bb conf_down_10y_bb plot_time, lcolor(green)) || ///
	(rcap conf_up_10y_bb conf_up_10y_bb plot_time, msize(*1) lcolor(green)) || ///
	(rcap conf_down_10y_bb conf_down_10y_bb plot_time, msize(*1) lcolor(green)) || ///
	(scatteri -8 5 0.3 5, c(l) m(i) lcolor(red) lpattern(dash)) ///
	, ///
	scheme(s1mono) ///
	legend(cols(1) ring(0) pos(7)  symxsize(2) ///
		order(2 "Intraday govPX on-the-run" 3 "Daily Bloomberg on-the-run" 4 "Daily GSW off-the-run curve"))
	graph export "../figures/figure7b.png", replace	